
const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`; // 标签名称
const qnameCapture = `((?:${ncname}\\:)?${ncname})`; // <span:xx></span>
const startTagOpen = new RegExp(`^<${qnameCapture}`); // 标签开头的正则，捕获内容是标签名
const startTagClose = /^\s*(\/?)>/; // 标签结束的  >
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`); // 匹配标签结尾
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g; //匹配{{xxx}}



export function parseHTML(html) {
    // 创建ast语法树
    function createASTElement(tag,attrs) {
        return {
            tag,
            attrs,
            children:[],
            type:1,
            parent:null
        }
    }
    let root; // 根元素
    let createParent; // 当前节点的父亲
    // 数据结构 栈
    let stack = []
    function start(tag,attr) { // 开始标签
        // console.log(tag,attr,'开始标签');
        let element = createASTElement(tag,attr)
        if(!root){
            root = element
        }
        createParent = element
        stack.push(element)
    }

    function charts(text) { // 文本
        // console.log(text,'文本');
        text = text.replace(/\s+/g,'') // 去掉空格
        if(text){
            createParent.children.push({
                type:3,
                text
            })
        }
    }

    function end(tag) { // 结束标签
        // console.log(tag,'结束标签');
        let element = stack.pop()
        createParent = stack[stack.length-1]
        if(createParent){
            element.parent = createParent.tag
            createParent.children.push(element)
        }
    }
    while(html){
     
        let textEnd = html.indexOf('<')
        if(textEnd === 0){
            
            const startTagMatch = parentStartTag() // 开始标签的内容
            if(startTagMatch){
                start(startTagMatch.tagName,startTagMatch.attrs)
                continue
            }
            
            // 结束标签
             let endTagMatch = html.match(endTag)
           
             if(endTagMatch) {
                advance(endTagMatch[0].length)
                end(endTagMatch[1])
                continue
             }
            
        }
        // 文本
        let text;
        if(textEnd > 0){
            // 获取到文本的内容
            text = html.substring(0,textEnd)
             
        }
        if(text){
            advance(text.length)
            charts(text)
        }
       
    }
    function parentStartTag() {
        // 获取开始标签
        const start = html.match(startTagOpen)
        if(start){
            // 变为ast对象
            let match = {
                tagName:start[1],
                attrs:[]
            }
            // 删除开始标签
            advance(start[0].length)
            // 添加属性
            // 注意：属性有多个，遍历
            // 注意：结束标签 >
            let attr
            let end
            
            while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {

                match.attrs.push({name:attr[1],value:(attr[3]||attr[4]||attr[5])})
                
                advance(attr[0].length)
                // console.log(match.attrs);
            }
          
            if(end){
                advance(end[0].length)
                return match
            }
       }

    }
    function advance(n) {
       html = html.substring(n)
    }

    return root
}